class VastApi
  class Listings
    class Entry
      attr_reader :doc, :vast, :_post_response
      def initialize(vast, doc)
        @doc = doc
        @attributes = {}
        @vast = vast
      end

      def [](var_name)
        @attributes[var_name] ||=
          if %W{id author link feeds updated published}.index(var_name)
            self.send(var_name)
          elsif %W{ title }.index(var_name)
            get_var('xmlns:'+var_name)
          else
            get_var("v:#{var_name}")
          end
      end

      def attributes
        vast_links
        @doc.children.each do |item|
          next if item.name == 'links'
          if %W{id author link feeds updated published}.index(item.name)
            self.send(item.name)
          else
            @attributes[item.name] ||= item.content
          end
        end
        @attributes
      end

      def id
        @attributes['id'] ||= get_var('v:item_id')
      end

      def link
        @attributes['link'] ||= get_var('xmlns:id')
      end

      def author
        @attributes['author'] ||= get_children(@doc.at_xpath('xmlns:author'))
      end

      def updated
        @attributes["updated"] ||= DateTime.strptime(@doc.at_xpath('xmlns:updated').content)
      end

      def published
        @attributes["published"] ||= DateTime.strptime(@doc.at_xpath('xmlns:published').content)
      end

      def vast_links
        if @attributes["vast_links"].nil?
          @attributes["vast_links"] = {}
          @doc.xpath('xmlns:link').each do |ln|
            attributes = ln.attributes
            @attributes["vast_links"][attributes['rel'].content] = {}
            attributes.each do |key, node|
              @attributes["vast_links"][attributes['rel'].content][key] = node.content
            end
          end
        end
        @attributes["vast_links"]
      end

      def req_fields
        res = Typhoeus::Request.get("http://leads.vast.com/leads/schema/#{self.id}/-/#{@vast.category}?apikey=#{@vast.api_key}&apihost=common.cars.data.vast.com")

        req = {'name_first' => true, 'name_last' => true, 'email' => true}
        doc = Nokogiri::XML(res.body)
        %W{street city regioncode postalcode}.each do |a|
          if (doc.at_css(a) && doc.at_css(a).attributes['required'])
            req.merge!(a => true)
          else
            req.merge!(a => false)
          end
        end
        req
      end

      def post_leads(params)
        entry = {
          "record_id" => "#{@vast.api_url}listings/#{self.id}/-/#{@vast.category}?apikey=#{@vast.api_key}",
          "adf" =>
          {
            "customer" =>
            {
              "comments" => params["comments"] || "",
              "contact"  =>
              {
                "phone"      => params["phone"] || "",
                "address"    =>
                {
                  "street_1"   => params["street_1"] || "",
                  "regioncode" => params["regioncode"] || "",
                  "postalcode" => params["postalcode"] || "",
                  "city"       => params["city"]} || "",
                  "email"      => params["email"] || "",
                  "name_last"  => params["name_last"] || "",
                  "name_first" => params["name_first"] || ""
              }
            }
          }
        }
        @_post_response = Typhoeus::Request.post("http://leads.vast.com/leads/-/#{@vast.category}?apikey=#{@vast.api_key}&apihost=common.cars.data.vast.com", :headers => {'Content-Type' => "application/atom+xml"}, :body => entry.to_xml(:root => 'entry', :dasherize => false))
        post_response
      end

      def post_response
        doc = Nokogiri::XML(@_post_response.body)
        impressions = doc.at_css('impressions')
        similar = doc.at_css('similar')
        {
          :status => doc.at_css("status")["code"],
          :message => doc.at_css('message').text,
          :similar => (similar) ? similar.text : '',
          :impressions => ((impressions) ? impressions.text : "")
        }
      end
      private

      def get_var(var_name)
        if var = @doc.at_xpath(var_name)
          var.text
        else
          nil
        end
      end

      def get_children(var)
        hash = {}
        var.children.each do |item|
          hash[item.name] = item.content
        end
        hash
      end

      def method_missing(sym, *args, &block)
        self[sym.to_s]
      end
    end
  end
end

